#pragma once
#include "comm/types.h"

#define EFLAGES_DEFAULT    (1 << 1)
#define EFLAGES_IF		   (1 << 9)

#pragma pack(1)
//段描述符
typedef struct global_segment_descriptor
{
    uint16_t limit15_0;		//段解析
	uint16_t base15_0;		//段基地址
	uint8_t  base23_16;		//段基地址
	uint16_t attr;			//段属性
	uint8_t  base31_24;		//段基地址
}global_segment_descriptor;

//TSS 段
typedef struct tss_t
{
    uint32_t pre_link;	
    uint32_t esp0, ss0, esp1, ss1, esp2, ss2;
    uint32_t cr3;
    uint32_t eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
    uint32_t es, cs, ss, ds, fs, gs;
    uint32_t ldt;               
    uint32_t iomap;		
}tss_t;

#pragma pack()

#define SEG_G	(1<<15)			//段偏移量的粒度 字节/4KB
#define SEG_D 	(1<<14)			//CPU工作模式    16/32
#define SEG_P   (1<<7)			//段在内存中是否存在

#define SEG_DPL0 (0<<5)		//特权级0
#define SEG_DPL3 (3<<5)		//特权级1

#define SEG_CPL0 (0<<0)		//特权级0
#define SEG_CPL3 (3<<0)		//特权级1

#define SEG_S_SYSTEM	(0<<4)	 //系统段
#define SEG_S_NORMAL 	(1<<4)	 //普通段

#define SEG_TYPE_CODE 	(1<<3)	 //代码段
#define SEG_TYPE_DATA 	(0<<3)	 //数据段
#define SEG_TYPE_TSS 	(9<<0)	 //TSS段

#define SEG_TYPE_RW 	(1<<1)	 //可读写

void set_global_segment(int selector,uint32_t base,uint32_t limit,uint16_t attr);
void cpu_init (void);
int  search_gdt_empty();
void switch_to_tss(int tss_sel);
void gdt_free_sel(int sel);


